package net.io;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class ChargenServer
{
	public static int DEFAULT_PORT = 19;
	public static void main(String[] args)
	{
		byte[] rotation = new byte[95*2];
		for (byte i = ' '; i <= '~'; i++)
		{
			rotation[i-' '] = i;
			rotation[i+95-' ']=i;
		}
		ServerSocketChannel serverSocketChannel;
		Selector selector = null;
		try
		{
			serverSocketChannel = ServerSocketChannel.open();
			ServerSocket ss = serverSocketChannel.socket();
			InetSocketAddress address = new InetSocketAddress(DEFAULT_PORT);
			ss.bind(address);
			serverSocketChannel.configureBlocking(false);
			selector = Selector.open();
			serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		}
		catch (Exception e)
		{
			return;
		}
		while(true)
		{
			try
			{
				selector.select();
			}
			catch (Exception e)
			{
				break;
			}
			Set<SelectionKey> readyKeys = selector.selectedKeys();
			Iterator<SelectionKey> iterator = readyKeys.iterator();
			while(iterator.hasNext())
			{
				SelectionKey key = (SelectionKey)iterator.next();
				iterator.remove();
				try
				{
					if(key.isAcceptable())
					{
						ServerSocketChannel server = (ServerSocketChannel) key.channel();
						SocketChannel client = server.accept();
						client.configureBlocking(false);
						SelectionKey keyTwo = client.register(selector, SelectionKey.OP_WRITE);
						ByteBuffer buffer = ByteBuffer.allocate(74);
						buffer.put(rotation,0,72);
						buffer.put((byte)'\r');
						buffer.put((byte)'\n');
						buffer.flip();
						keyTwo.attach(buffer);
					}
					else if(key.isWritable())
					{
						SocketChannel client = (SocketChannel) key.channel();
						ByteBuffer buffer = (ByteBuffer) key.attachment();
						if(!buffer.hasRemaining())
						{
							buffer.rewind();
							int first = buffer.get();
							buffer.rewind();
							int position = first -' '+1;
							buffer.put(rotation,position,72);
							buffer.put((byte)'\r');
							buffer.put((byte)'\n');
							buffer.flip();
						}
						client.write(buffer);
					}
				}
				catch (Exception e)
				{
					key.cancel();
					try
					{
						key.channel().close();
					}
					catch (Exception e2)
					{
					}
				}
			}
		}
	}
}
